<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      v-loading="formLoading"
    >
      <el-form-item label="商家名称" prop="merchantId">
        <el-select 
          v-model="formData.merchantId" 
          placeholder="请选择商家" 
          filterable 
          :loading="merchantLoading"
          class="w-full"
          popper-class="account-select-dropdown"
          clearable
          @focus="handleSelectFocus"
          @visible-change="handleVisibleChange"
          @filter-method="handleSearch"
        >
          <el-option
            v-for="item in merchantList"
            :key="item.id"
            :label="item.merchantName"
            :value="item.id"
          />
          <template #dropdown>
            <div class="merchant-select-content">
              <div v-if="merchantList.length === 0" class="merchant-empty">
                <el-empty description="暂无数据" />
              </div>
              <div v-if="hasMore && !merchantLoading" class="merchant-loading">
                <el-icon class="is-loading"><Loading /></el-icon>
                <span class="loading-text">加载更多...</span>
              </div>
            </div>
          </template>
        </el-select>
      </el-form-item>
      <el-form-item label="用户昵称" prop="userId">
        <el-select 
          v-model="formData.userId" 
          placeholder="请输入用户昵称搜索" 
          filterable 
          :loading="userLoading"
          class="w-full"
          popper-class="user-select-dropdown"
          clearable
          @focus="handleUserSelectFocus"
          @visible-change="handleUserVisibleChange"
          @filter-method="handleUserSearch"
        >
          <el-option
            v-for="item in userList"
            :key="item.id"
            :label="item.nickname"
            :value="item.id"
          />
          <template #dropdown>
            <div class="user-select-content">
              <div v-if="userList.length === 0" class="user-empty">
                <el-empty description="暂无数据" />
              </div>
              <div v-if="userHasMore && !userLoading" class="user-loading">
                <el-icon class="is-loading"><Loading /></el-icon>
                <span class="loading-text">加载更多...</span>
              </div>
            </div>
          </template>
        </el-select>
      </el-form-item>
      <el-form-item label="用户类型" prop="relationType">
        <el-select v-model="formData.relationType" placeholder="请选择用户类型">
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.JULIANG_RELATION_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio
            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
            :key="dict.value"
            :label="dict.value"
          >
            {{ dict.label }}
          </el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
import { MerchantUserApi, MerchantUserVO } from '@/api/juliang/merchantuser'
import { MerchantApi, MerchantVO } from '@/api/juliang/merchant'
import { Loading } from '@element-plus/icons-vue'
import { throttle, debounce } from 'lodash-es'
import * as UserApi from '@/api/member/user'
/** 商家和小程序用户关联 表单 */
defineOptions({ name: 'MerchantUserForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const merchantList = ref<MerchantVO[]>([]) // 商家列表
const merchantLoading = ref(false) // 商家列表加载状态
const hasMore = ref(true) // 是否还有更多数据
const loadingNewPage = ref(false) // 标记是否正在加载新页面
const searchKeyword = ref('') // 搜索关键字

const merchantQuery = reactive({
  pageNo: 1,
  pageSize: 10,
  merchantName: undefined as string | undefined
})

// 用户相关
const userList = ref<any[]>([]) // 用户列表
const userLoading = ref(false) // 用户列表加载状态
const userHasMore = ref(true) // 是否还有更多数据
const userLoadingNewPage = ref(false) // 标记是否正在加载新页面
const userSearchKeyword = ref('') // 搜索关键字

const userQuery = reactive({
  pageNo: 1,
  pageSize: 10,
  nickname: undefined as string | undefined
})

const formData = ref({
  id: undefined,
  merchantId: undefined,
  userId: undefined,
  relationType: undefined,
  status: 0,
})
const formRules = reactive({
  merchantId: [{ required: true, message: '商家不能为空', trigger: 'change' }],
  userId: [{ required: true, message: '小程序用户', trigger: 'blur' }],
  relationType: [{ required: true, message: '关联类型不能为空', trigger: 'change' }],
})
const formRef = ref() // 表单 Ref

/** 获取商家列表 */
const getMerchantList = async (isLoadMore = false) => {
  if (merchantLoading.value || (isLoadMore && !hasMore.value)) return
  
  if (isLoadMore) {
    loadingNewPage.value = true
  } else {
    merchantLoading.value = true
  }

  try {
    const data = await MerchantApi.getMerchantPage({
      pageNo: merchantQuery.pageNo,
      pageSize: merchantQuery.pageSize,
      merchantName: searchKeyword.value
    })
    
    if (data?.list?.length > 0) {
      merchantList.value = isLoadMore 
        ? [...merchantList.value, ...data.list]
        : data.list
      hasMore.value = data.list.length === merchantQuery.pageSize
    } else {
      if (!isLoadMore) {
        merchantList.value = []
      }
      hasMore.value = false
    }
  } catch (error) {
    console.error('获取商家列表失败:', error)
    message.error('获取商家列表失败')
    if (!isLoadMore) {
      merchantList.value = []
    }
  } finally {
    merchantLoading.value = false
    loadingNewPage.value = false
  }
}

/** 监听下拉框滚动 */
const handleDropdownScroll = throttle(async (e: Event) => {
  const target = e.target as HTMLElement
  const { scrollTop, scrollHeight, clientHeight } = target
  
  // 距离底部50px时预加载下一页
  if (scrollHeight - scrollTop - clientHeight < 50 && hasMore.value && !loadingNewPage.value) {
    merchantQuery.pageNo++
    await getMerchantList(true)
  }
}, 200)

/** 处理下拉框显示状态变化 */
const handleVisibleChange = (visible: boolean) => {
  if (visible) {
    // 下拉框显示时，添加滚动监听
    nextTick(() => {
      const dropdownWrapper = document.querySelector('.account-select-dropdown .el-select-dropdown__wrap')
      if (dropdownWrapper) {
        dropdownWrapper.addEventListener('scroll', handleDropdownScroll)
      }
    })
  } else {
    // 下拉框隐藏时，移除滚动监听
    const dropdownWrapper = document.querySelector('.account-select-dropdown .el-select-dropdown__wrap')
    if (dropdownWrapper) {
      dropdownWrapper.removeEventListener('scroll', handleDropdownScroll)
    }
  }
}

/** 处理搜索 */
const handleSearch = debounce((query: string) => {
  searchKeyword.value = query.trim()
  merchantQuery.pageNo = 1
  hasMore.value = true
  merchantList.value = []
  getMerchantList()
}, 300)

/** 处理下拉框获得焦点 */
const handleSelectFocus = () => {
  if (merchantList.value.length === 0) {
    searchKeyword.value = ''
    merchantQuery.pageNo = 1
    hasMore.value = true
    getMerchantList()
  }
}

/** 获取用户列表 */
const getUserList = async (isLoadMore = false) => {
  if (userLoading.value || (isLoadMore && !userHasMore.value)) return
  
  if (isLoadMore) {
    userLoadingNewPage.value = true
  } else {
    userLoading.value = true
  }

  try {
    const data = await UserApi.getUserPage({
      pageNo: userQuery.pageNo,
      pageSize: userQuery.pageSize,
      nickname: userSearchKeyword.value
    })
    
    if (data?.list?.length > 0) {
      userList.value = isLoadMore 
        ? [...userList.value, ...data.list]
        : data.list
      userHasMore.value = data.list.length === userQuery.pageSize
    } else {
      if (!isLoadMore) {
        userList.value = []
      }
      userHasMore.value = false
    }
  } catch (error) {
    console.error('获取用户列表失败:', error)
    message.error('获取用户列表失败')
    if (!isLoadMore) {
      userList.value = []
    }
  } finally {
    userLoading.value = false
    userLoadingNewPage.value = false
  }
}

/** 监听用户下拉框滚动 */
const handleUserDropdownScroll = throttle(async (e: Event) => {
  const target = e.target as HTMLElement
  const { scrollTop, scrollHeight, clientHeight } = target
  
  if (scrollHeight - scrollTop - clientHeight < 50 && userHasMore.value && !userLoadingNewPage.value) {
    userQuery.pageNo++
    await getUserList(true)
  }
}, 200)

/** 处理用户下拉框显示状态变化 */
const handleUserVisibleChange = (visible: boolean) => {
  if (visible) {
    nextTick(() => {
      const dropdownWrapper = document.querySelector('.user-select-dropdown .el-select-dropdown__wrap')
      if (dropdownWrapper) {
        dropdownWrapper.addEventListener('scroll', handleUserDropdownScroll)
      }
    })
  } else {
    const dropdownWrapper = document.querySelector('.user-select-dropdown .el-select-dropdown__wrap')
    if (dropdownWrapper) {
      dropdownWrapper.removeEventListener('scroll', handleUserDropdownScroll)
    }
  }
}

/** 处理用户搜索 */
const handleUserSearch = debounce((query: string) => {
  userSearchKeyword.value = query.trim()
  userQuery.pageNo = 1
  userHasMore.value = true
  userList.value = []
  getUserList()
}, 300)

/** 处理用户下拉框获得焦点 */
const handleUserSelectFocus = () => {
  if (userList.value.length === 0) {
    userSearchKeyword.value = ''
    userQuery.pageNo = 1
    userHasMore.value = true
    getUserList()
  }
}

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()
  // 修改时，设置数据
  if (id) {
    formLoading.value = true
    try {
      formData.value = await MerchantUserApi.getMerchantUserById(id)
    } finally {
      formLoading.value = false
    }
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  // 校验表单
  await formRef.value.validate()
  // 提交请求
  formLoading.value = true
  try {
    const data = formData.value as unknown as MerchantUserVO
    if (formType.value === 'create') {
      await MerchantUserApi.createMerchantUser(data)
      message.success(t('common.createSuccess'))
    } else {
      await MerchantUserApi.updateMerchantUser(data)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    merchantId: undefined,
    userId: undefined,
    relationType: undefined,
    status: undefined,
  }
  formRef.value?.resetFields()
  // 重置商家相关的状态
  merchantList.value = []
  hasMore.value = true
  merchantQuery.pageNo = 1
  searchKeyword.value = ''
  // 重置用户相关的状态
  userList.value = []
  userHasMore.value = true
  userQuery.pageNo = 1
  userSearchKeyword.value = ''
}
</script>

<style lang="scss" scoped>
.merchant-select-content {
  .merchant-empty {
    padding: 20px;
    text-align: center;
  }
  
  .merchant-loading {
    padding: 8px 0;
    text-align: center;
    background-color: var(--el-bg-color);
    border-top: 1px solid var(--el-border-color-lighter);
    
    .el-icon {
      margin-right: 6px;
      font-size: 16px;
      color: var(--el-color-primary);
      vertical-align: middle;
    }
    
    .loading-text {
      font-size: 13px;
      color: var(--el-text-color-secondary);
      vertical-align: middle;
    }
  }
}

:deep(.el-select-dropdown__wrap) {
  max-height: 300px;
}

:deep(.el-select-dropdown__list) {
  padding: 0;
}

.user-select-content {
  .user-empty {
    padding: 20px;
    text-align: center;
  }
  
  .user-loading {
    padding: 8px 0;
    text-align: center;
    background-color: var(--el-bg-color);
    border-top: 1px solid var(--el-border-color-lighter);
    
    .el-icon {
      margin-right: 6px;
      font-size: 16px;
      color: var(--el-color-primary);
      vertical-align: middle;
    }
    
    .loading-text {
      font-size: 13px;
      color: var(--el-text-color-secondary);
      vertical-align: middle;
    }
  }
}

:deep(.el-select-dropdown__wrap) {
  max-height: 300px;
}

:deep(.el-select-dropdown__list) {
  padding: 0;
}
</style>